import type {Router, RouteLocationNormalized, NavigationGuardNext} from 'vue-router'
import {ref, nextTick} from 'vue'
import NProgress from 'nprogress'
import {useSettingStore} from '@/store/modules/setting'
import {useUserStore} from '@/store/modules/user'
import {useMenuStore} from '@/store/modules/menu'
import {setWorktab} from '@/utils/navigation'
import {setPageTitle} from '../utils/utils'
import {registerDynamicRoutes} from '../utils/registerRoutes'
import {AppRouteRecord} from '@/types/router'
import {RoutesAlias} from '../routesAlias'
import {menuDataToRouter} from '../utils/menuToRouter'
import {asyncRoutes} from '../routes/asyncRoutes'
import {staticRoutes} from '../routes/staticRoutes'
import {loadingService} from '@/utils/ui'
import {useCommon} from '@/composables/useCommon'
import {useWorktabStore} from '@/store/modules/worktab'
import {getUserInfo} from '@/api/user'
import {getMenuList} from '@/api/menu'
import {makeTree, arrayGroupBy, arrayValueToKey} from '@/utils/helper'

// 是否已注册动态路由
const isRouteRegistered = ref(false)

// 跟踪是否需要关闭 loading
const pendingLoading = ref(false)

/**
 * 设置路由全局前置守卫
 */
export function setupBeforeEachGuard(router: Router): void {
	router.beforeEach(
		async (
			to: RouteLocationNormalized,
			from: RouteLocationNormalized,
			next: NavigationGuardNext
		) => {
			try {
				await handleRouteGuard(to, from, next, router)
			} catch (error) {
				console.error('路由守卫处理失败:', error)
				next('/exception/500')
			}
		}
	)

	// 设置后置守卫以关闭 loading 和进度条
	setupAfterEachGuard(router)
}

/**
 * 设置路由全局后置守卫
 */
function setupAfterEachGuard(router: Router): void {
	router.afterEach(() => {
		// 关闭进度条
		const settingStore = useSettingStore()
		if (settingStore.showNprogress) {
			NProgress.done()
		}

		// 关闭 loading 效果
		if (pendingLoading.value) {
			nextTick(() => {
				loadingService.hideLoading()
				pendingLoading.value = false
			})
		}
	})
}

/**
 * 处理路由守卫逻辑
 */
async function handleRouteGuard(
	to: RouteLocationNormalized,
	from: RouteLocationNormalized,
	next: NavigationGuardNext,
	router: Router
): Promise<void> {
	const settingStore = useSettingStore()
	const userStore = useUserStore()

	// 处理进度条
	if (settingStore.showNprogress) {
		NProgress.start()
	}

	// 处理登录状态
	if (!(await handleLoginStatus(to, userStore, next))) {
		return
	}

	// 处理动态路由注册
	if (!isRouteRegistered.value && userStore.isLogin) {
		await handleDynamicRoutes(to, from, next, router)
		return
	}

	// 处理根路径跳转到首页
	if (userStore.isLogin && isRouteRegistered.value && handleRootPathRedirect(to, next)) {
		return
	}

	// 处理已知的匹配路由
	if (to.matched.length > 0) {
		setWorktab(to)
		setPageTitle(to)
		next()
		return
	}

	// 尝试刷新路由重新注册
	if (userStore.isLogin && !isRouteRegistered.value) {
		await handleDynamicRoutes(to, from, next, router)
		return
	}

	// 未匹配到路由，跳转到 404
	next(RoutesAlias.Exception404)
}

/**
 * 处理登录状态
 */
async function handleLoginStatus(
	to: RouteLocationNormalized,
	userStore: ReturnType<typeof useUserStore>,
	next: NavigationGuardNext
): Promise<boolean> {
	// 检查是否为静态路由
	const isStaticRoute = isRouteInStaticRoutes(to.path)

	if (!userStore.isLogin && to.path !== RoutesAlias.Login && !isStaticRoute) {
		userStore.logOut()
		next(RoutesAlias.Login)
		return false
	}
	return true
}

/**
 * 检查路由是否为静态路由
 */
function isRouteInStaticRoutes(path: string): boolean {
	const checkRoute = (routes: any[], targetPath: string): boolean => {
		return routes.some((route) => {
			if (route.path === targetPath) {
				return true
			}
			if (route.children && route.children.length > 0) {
				return checkRoute(route.children, targetPath)
			}
			return false
		})
	}

	return checkRoute(staticRoutes, path)
}

/**
 * 处理动态路由注册
 */
async function handleDynamicRoutes(
	to: RouteLocationNormalized,
	from: RouteLocationNormalized,
	next: NavigationGuardNext,
	router: Router
): Promise<void> {
	try {
		// 显示 loading 并标记 pending
		pendingLoading.value = true
		loadingService.showLoading()

		// 获取用户信息
		const userStore = useUserStore()
		const isRefresh = from.path === '/'
		if (isRefresh || !userStore.info || Object.keys(userStore.info).length === 0) {
			try {
				const data: any = await getUserInfo()
				userStore.setUserInfo(data)
			} catch (error) {
				console.error('获取用户信息失败', error)
			}
		}

		await getMenuData(router)

		// 处理根路径跳转
		if (handleRootPathRedirect(to, next)) {
			return
		}

		next({
			path: to.path,
			query: to.query,
			hash: to.hash,
			replace: true
		})
	} catch (error) {
		console.error('动态路由注册失败:', error)
		next('/exception/500')
	}
}

/**
 * 获取菜单数据
 */
async function getMenuData(router: Router): Promise<void> {
	try {
		if (useCommon().isFrontendMode.value) {
			await processFrontendMenu(router)
		} else {
			await processBackendMenu(router)
		}
	} catch (error) {
		handleMenuError(error)
		throw error
	}
}

/**
 * 处理前端控制模式的菜单逻辑
 */
async function processFrontendMenu(router: Router): Promise<void> {
	const menuList = asyncRoutes.map((route) => menuDataToRouter(route))
	/*const userStore = useUserStore()
	const roles = userStore.info.roles*/
	const roles = ['R_SUPER']

	if (!roles) {
		throw new Error('获取用户角色失败')
	}

	const filteredMenuList = filterMenuByRoles(menuList, roles)

	await registerAndStoreMenu(router, filteredMenuList)
}

/**
 * 处理后端控制模式的菜单逻辑
 */
async function processBackendMenu(router: Router): Promise<void> {
	try {
		const {list}: any = await getMenuList({page: 1, limit: 1000});
		const menuGroup: any = arrayGroupBy(list, ['type']);
		const menu = menuGroup[1] ?? [];
		const permission = (menuGroup[2] ?? []).map((el: any) => {
			return {
				id: el.menuId,
				pid: el.pid,
				title: el.name,
				authMark: el.permissionMark,
			};
		});
		const permissionFormat: any = arrayValueToKey(permission, 'id');
		const permissionGroup: any = arrayGroupBy(permission, ['pid']);
		for(let k in permissionGroup){
			if (permissionFormat[k]) {
				permissionGroup[permissionFormat[k].pid] = [...permissionGroup[permissionFormat[k].pid], ...permissionGroup[k]];
			}
		}
		const backendMenu: any[] = [];
		menu.forEach((item: any) => {
			const params: any = JSON.parse(item.pathParams);
			const query: any = JSON.parse(item.queryParams);
			backendMenu.push({
				id: item.menuId,
				pid: item.pid,
				path: item.route,
				name: item.name,
				component: item.path,
				meta: {
					icon: item.icon,
					title: item.title,
					isHide: item.isHide === 1,
					isHideTab: item.isHideTab === 1,
					activePath: item.activePath,
					keepAlive: item.isKeepAlive === 1,
					fixedTab: item.isFixedTab === 1,
					isIframe: item.isIframe === 1,
					showBadge: item.isBadge === 1,
					showTextBadge: item.badgeText,
					authList: permissionGroup[item.menuId] ?? [],
					isFullPage: item.isFullPage === 1,
					query: query,
					params: params,
				}
			});
		});
		const finalMenuList = makeTree(backendMenu, 'id', 'pid', 0).map((route) => menuDataToRouter(route));
		await registerAndStoreMenu(router, finalMenuList)
	} catch (error) {
		useUserStore().logOut();
	}
}

/**
 * 递归过滤空菜单项
 */
function filterEmptyMenus(menuList: AppRouteRecord[]): AppRouteRecord[] {
	return menuList
		.map((item) => {
			// 如果有子菜单，先递归过滤子菜单
			if (item.children && item.children.length > 0) {
				const filteredChildren = filterEmptyMenus(item.children)
				return {
					...item,
					children: filteredChildren
				}
			}
			return item
		})
		.filter((item) => {
			// 过滤掉布局组件且没有子菜单的项
			const isEmptyLayoutMenu =
				item.component === RoutesAlias.Layout && (!item.children || item.children.length === 0)

			// 过滤掉组件为空字符串且没有子菜单的项，但保留有外链的菜单项
			const isEmptyComponentMenu =
				item.component === '' &&
				(!item.children || item.children.length === 0) &&
				item.meta.isIframe !== true &&
				!item.meta.link

			return !(isEmptyLayoutMenu || isEmptyComponentMenu)
		})
}

/**
 * 注册路由并存储菜单数据
 */
async function registerAndStoreMenu(router: Router, menuList: AppRouteRecord[]): Promise<void> {
	if (!isValidMenuList(menuList)) {
		throw new Error('获取菜单列表失败，请重新登录')
	}
	const menuStore = useMenuStore()
	// 递归过滤掉为空的菜单项
	const list = filterEmptyMenus(menuList)
	menuStore.setMenuList(list)
	registerDynamicRoutes(router, list)
	isRouteRegistered.value = true
	useWorktabStore().validateWorktabs(router)
}

/**
 * 处理菜单相关错误
 */
function handleMenuError(error: unknown): void {
	console.error('菜单处理失败:', error)
	useUserStore().logOut()
	throw error instanceof Error ? error : new Error('获取菜单列表失败，请重新登录')
}

/**
 * 根据角色过滤菜单
 */
const filterMenuByRoles = (menu: AppRouteRecord[], roles: string[]): AppRouteRecord[] => {
	return menu.reduce((acc: AppRouteRecord[], item) => {
		const itemRoles = item.meta?.roles
		const hasPermission = !itemRoles || itemRoles.some((role) => roles?.includes(role))

		if (hasPermission) {
			const filteredItem = {...item}
			if (filteredItem.children?.length) {
				filteredItem.children = filterMenuByRoles(filteredItem.children, roles)
			}
			acc.push(filteredItem)
		}

		return acc
	}, [])
}

/**
 * 验证菜单列表是否有效
 */
function isValidMenuList(menuList: AppRouteRecord[]): boolean {
	return Array.isArray(menuList) && menuList.length > 0
}

/**
 * 重置路由相关状态
 */
export function resetRouterState(): void {
	isRouteRegistered.value = false
	const menuStore = useMenuStore()
	menuStore.removeAllDynamicRoutes()
	menuStore.setMenuList([])
}

/**
 * 处理根路径跳转到首页
 */
function handleRootPathRedirect(to: RouteLocationNormalized, next: NavigationGuardNext): boolean {
	if (to.path === '/') {
		const {homePath} = useCommon()
		if (homePath.value && homePath.value !== '/') {
			next({path: homePath.value, replace: true})
			return true
		}
	}
	return false
}
